import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;

import java.security.*;
import java.security.cert.CertificateException;
import javax.net.ssl.*;
import java.io.*;
import java.net.*;

public class main  extends Thread implements ActionListener,MouseListener{
	SSLSocket newsock;
	JFrame			 mainframe		=new JFrame("Server");
	JButton 		 login;
   	JLabel 			 UserName 		= new JLabel("User Name :");
   	JLabel 			 Pass 			= new JLabel("Password :");
   	JTextField 		 TextUserName 	= new JTextField(15);
   	JPasswordField 		 TextPass 		= new JPasswordField(15);
   	//ServerSocket	 server 		= null;
   //	Socket 			 client 		= null;

   	BufferedWriter   outme			=null;
   	String 			 line;
   	static  student  S				=new student();
   			Admin    admin			=new Admin();
   	static  Professor P				=new Professor();
   	static  TA TA				=new TA();
    static 	main 	 frame;
   	public final 	ReferenceMonitor RM		=new ReferenceMonitor();
    private static 	JPanel	mainpanel 		= new JPanel();
    private static 	JPanel 	west 			= new JPanel();
    private static 	JPanel  center 		= new JPanel();
    private static	JPanel  cont			=new JPanel();
    int 			numberofclient  =1;
    static boolean check=true;
    static boolean  listen=false;
    private static 	JLabel	keystorepassword			=new JLabel("Key store password:");
    private static	JTextField keystorepasswordvalue	=new JTextField(20);
    public 		static 		JLabel statuslbl 				= new JLabel();
    //main m=new main();
   
   	main(SSLSocket s,int n)
   	{
   		numberofclient=n;
   		newsock=s;
   		System.out.println("fa");
   	}
	main(){ //Begin Constructor
	   } //End Constructor
	public void run()
   	{
   		
   		  try{ 
   			 BufferedReader inp = new BufferedReader(new InputStreamReader(newsock.getInputStream()));
				PrintStream outp = new PrintStream(newsock.getOutputStream(), true);
   		 
   		 boolean morerequests=true;
   		    while(morerequests){
   		      try{
   		    	//read from client 
	   		     line=inp.readLine();
	   		     String[] result = line.split(";");
   		         //for (int x=0; x<result.length; x++)
   		        	 
   		           //System.out.println("Check whether btn pressed " +result[x]);
   		        if (result[0].equals("S"))
   		        {
   		        	//String s=null;
   		        	//con.gettranscript(result[1]);
   		        	String res=S.getaction(result);
   		            outp.println(res);	
   		        }
   		        else if(result[0].equals("P"))
   		        {	
   		        	String s=P.getaction(result);
   		        	System.out.println(s);
   		        	outp.println(s);
   		        }
   		        else if(result[0].equals("T"))
   		        {
   		        	String s=null;
   		        	 s=TA.getaction(result);
   		        	System.out.println("Server Main: T"+s);
   		            outp.println(s);
   		        }
   		 
   		        else if (result[0].equals("login"))
   		        {
   		         String res=S.getaction(result);
   		         outp.println(res);
   		        }
   		        else if(result[0].equals("checkUser"))
   		        {
   		        	String res;
   		        	res = RM.check_authenticated_user(result[1], result[2]);
   		        	outp.println(res);
   		        }
   		     else if (result[0].equals("Rigester"))
             {
   		    	 
              String res=RM.Rigester(result);
              outp.println(res);
              
             }
   		    
   		        else
   		        {
  		        	outp.println( "stop" );	
   		        	
   		        }
   		      	} catch (IOException e) {
   		        System.out.println("Read failed");
   		        System.exit(-1);
   		      }
   		   
   		    }	
   		 outp.close();
         inp.close();
         newsock.close();
 
   	 } catch (Exception ee) {
         System.err.println(ee.toString());
      }
   	}

   	public void maininterface()
   	{	Dimension FrameSize=new Dimension(1200,800);
   		mainframe.setSize(1100, 600);
   		login = new JButton("Log in");
        mainframe.getContentPane().setPreferredSize(FrameSize);
        mainframe.setLayout(new BorderLayout());
        center.setSize(1000,700);
        //center.setLayout(new GridLayout(8,1));
        center.add(UserName);
        center.add(TextUserName);
        center.add(Pass);
        center.add(TextPass);
        center.add(keystorepassword);
        center.add(keystorepasswordvalue);
        center.add(login);
        center.add(statuslbl);
        
        login.addActionListener(this);
        mainpanel.add(center,BorderLayout.CENTER);
        mainpanel.add(west,BorderLayout.WEST);
        mainframe.getContentPane().add(mainpanel);
        mainframe.setVisible(true);
   	}
  public void actionPerformed(ActionEvent event) {
//	  if (==JComboBox)
//	  {
//		  JComboBox cb = (JComboBox)event.getSource();
//	  }
//	  else{ 
//     }
	  boolean ckeck=false;
	  System.out.println(event.getActionCommand());
	  Object source = event.getSource();
    // JComboBox cb= (JComboBox) event.getSource();
     if(source == login){
    	    String res = null;
    	    if(!keystorepasswordvalue.getText().isEmpty())
    	    {
			try {
				res = RM.check_authenticated_admin(TextUserName.getText(), TextPass.getText());
			} catch (NoSuchAlgorithmException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
    	    if (res.equals("Authenticated"))
    	    {
    	    	ckeck=true;
    	 	mainpanel.removeAll();
    	 	mainpanel.setLayout(new BorderLayout());
         	admin.CreateAccount.addActionListener(this);
         	admin.AddnewAccount.addActionListener(this);
         	mainpanel.add(admin.Interfase(),BorderLayout.WEST);
         	mainpanel.add(admin.InterfaceNorth(),BorderLayout.NORTH);
         	//mainpanel.add(admin.CreateAccountinterface(),BorderLayout.CENTER);
         	//mainpanel.add(admin.SouthPanel(false,true),BorderLayout.SOUTH);
         	mainpanel.revalidate();
         	mainpanel.repaint();
         	//action listener 
         	admin.id=TextUserName.getText();	
          	admin.AsignCourse.addActionListener(this);
            admin.Addcourse.addActionListener(this);
            admin.ShowLog.addActionListener(this);
            admin.AddcourseToDB.addActionListener(this);
            admin.Adminassign.addActionListener(this);
            admin.DataBaseTable.addMouseListener(this);
            admin.submitbtn.addActionListener(this);
     		admin.searchbtn.addActionListener(this);
            source=admin.CreateAccount;
            listen=true;
    	    }else{
    	    	center.removeAll();
    	    	statuslbl.setText("Not A");
    	    	maininterface();
    	    	statuslbl.setOpaque(true);
		 	    statuslbl.setBackground(Color.RED);
		 	    statuslbl.setForeground(Color.WHITE);
				statuslbl.setBounds(12,190,300,40);
    	    }
    	    }
    	    else{
    	    	center.removeAll();
    	    	statuslbl.setText("Not A");
    	    	maininterface();
    	    	statuslbl.setOpaque(true);
		 	    statuslbl.setBackground(Color.RED);
		 	    statuslbl.setForeground(Color.WHITE);
				statuslbl.setBounds(12,190,300,40);}
        
     }
     // ############################ Activate Accounts ############################
      if (source== admin.CreateAccount)
     {
    	 String[][] line=RM.Get_Users_Accounts(admin.id);
    	 mainpanel.removeAll( );
 	 	 mainpanel.setLayout(new BorderLayout( ) );
      	 mainpanel.add(admin.Interfase( ) , BorderLayout.WEST );
      	 mainpanel.add(admin.InterfaceNorth( ), BorderLayout.NORTH );
      	 mainpanel.add(admin.GetAccounts(line) , BorderLayout.CENTER );
      	// mainpanel.add(admin.SouthPanel( true , false ) , BorderLayout.SOUTH );
      	 mainpanel.revalidate( );
      	 mainpanel.repaint( );
 		//Admin.DataBaseTable.addMouseListener(this);
//      	Admin.submitbtn.addActionListener(this);
// 		Admin.searchbtn.addActionListener(this);
     }
     else if (source == admin.submitbtn)
     {
    	 String line=admin.usernametxt.getText();
    	 RM.Update_Accounts(line, admin.id);
    	 String[][] linee=RM.Get_Users_Accounts(admin.id);
    	 mainpanel.removeAll( );
 	 	 mainpanel.setLayout(new BorderLayout( ) );
      	 mainpanel.add(admin.Interfase( ) , BorderLayout.WEST );
      	 mainpanel.add(admin.InterfaceNorth( ), BorderLayout.NORTH );
      	 mainpanel.add(admin.GetAccounts(linee) , BorderLayout.CENTER );
      	 // mainpanel.add(admin.SouthPanel( true , false ) , BorderLayout.SOUTH );
      	 mainpanel.revalidate( );
      	 mainpanel.repaint( );
 		//Admin.DataBaseTable.addMouseListener(this);
 		//Admin.submitbtn.addActionListener(this);
     }
     
    else if( source == admin.searchbtn)
    {
    	System.out.println("Search BTN");
    	 String[][] line=RM.Get_Users_Accountss(admin.id, admin.searchtxt.getText());
    	 mainpanel.removeAll( );
 	 	 mainpanel.setLayout(new BorderLayout( ) );
      	 mainpanel.add(admin.Interfase( ) , BorderLayout.WEST );
      	 mainpanel.add(admin.InterfaceNorth( ), BorderLayout.NORTH );
      	 mainpanel.add(admin.GetAccounts( line ) , BorderLayout.CENTER );
      	 //mainpanel.add(admin.SouthPanel( "No user found" ) , BorderLayout.SOUTH );
      	 mainpanel.revalidate( );
      	 mainpanel.repaint( );
 		//Admin.DataBaseTable.addMouseListener(this);
 		//Admin.searchbtn.addActionListener(this);
    	
    	
    }
     else if ( source == admin.AsignCourse )
     {
    	// admin.Semlistwithevents.setSelectedIndex(0);
    	String s = RM.getCourseNumbers();
    	// String s =RM.Filtercourselistbyterm(admin.Semlistwithevents.getSelectedItem().toString());
    	 mainpanel.removeAll( );
 	 	 mainpanel.setLayout( new BorderLayout( ) );
      	 mainpanel.add( admin.Interfase( ) , BorderLayout.WEST);
      	 mainpanel.add( admin.InterfaceNorth( ) , BorderLayout.NORTH );
      	 mainpanel.add( admin.AssignRole( s ) , BorderLayout.CENTER );
      //	 mainpanel.add( admin.SouthPanel( false , true ) , BorderLayout.SOUTH );
      	 mainpanel.revalidate( );
         admin.Semlistwithevents.addActionListener( this );
      	 mainpanel.repaint( );
     }
     
     else if ( source==admin.Semlistwithevents )
     {
    	 String s =RM.Filtercourselistbyterm(admin.Semlistwithevents.getSelectedItem().toString());
    	 int i=admin.Semlistwithevents.getSelectedIndex();
    	 mainpanel.removeAll( );
 	 	 mainpanel.setLayout( new BorderLayout( ) );
      	 mainpanel.add( admin.Interfase( ) , BorderLayout.WEST);
      	 mainpanel.add( admin.InterfaceNorth( ) , BorderLayout.NORTH );
      	 mainpanel.add( admin.AssignRole( s ) , BorderLayout.CENTER );
      	// mainpanel.add( admin.SouthPanel( false , true ) , BorderLayout.SOUTH );
      	 admin.Semlistwithevents.setSelectedIndex( i );
      	 mainpanel.revalidate( );
      	 mainpanel.repaint( );
         admin.Semlistwithevents.addActionListener( this );
     }

     else if ( source == admin.ShowLog )
     { 
    	String[][] line=RM.Get_admin_log(admin.id);
    	 mainpanel.removeAll( );
 	 	 mainpanel.setLayout(new BorderLayout( ) );
      	 mainpanel.add(admin.Interfase( ) , BorderLayout.WEST );
      	 mainpanel.add(admin.InterfaceNorth( ), BorderLayout.NORTH );
      	 mainpanel.add(admin.logtabel(line) , BorderLayout.CENTER );
      //	 mainpanel.add(admin.SouthPanel( true , false ) , BorderLayout.SOUTH );
      	 mainpanel.revalidate( );
      	 mainpanel.repaint( );
      	
     }
     else if (source==admin.Addcourse)
     { 
    	 System.out.println("addcourse");
    	 mainpanel.removeAll();
 	 	 mainpanel.setLayout(new BorderLayout());
      	 mainpanel.add(admin.Interfase(),BorderLayout.WEST);
      	 mainpanel.add(admin.InterfaceNorth(),BorderLayout.NORTH);
      	 mainpanel.add(admin.Addcourse(),BorderLayout.CENTER);
      //	 mainpanel.add(admin.SouthPanel( false, true ),BorderLayout.SOUTH);
      	 mainpanel.revalidate();
      	 mainpanel.repaint();
     }
     
     else if (source==admin.Adminassign)
     {
    	 //System.out.println("Admin Assign");
    	// int index=Admin.Sv
    	 System.out.println(Admin.SemList.getSelectedItem());
    	int  index=admin.Semlistwithevents.getSelectedIndex();
    			 //;
    			 //SemList.getSelectedIndex();
    		
    	 String check=null;
		try {
			check = RM.AssignRole(admin.id,admin.Role.getSelectedItem().toString(),admin.Semlistwithevents.getSelectedItem().toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	 //System.out.println(admin.SemList.getSelectedItem().toString());
    	 String s=RM.getCourseNumbers( );
    	 mainpanel.removeAll( );
	 	 mainpanel.setLayout(new BorderLayout( ) );
     	 mainpanel.add(admin.Interfase( ) , BorderLayout.WEST);
     	 mainpanel.add(admin.InterfaceNorth( ) , BorderLayout.NORTH);
     	 mainpanel.add(admin.AssignRole( s ) , BorderLayout.CENTER);
     	 mainpanel.add(admin.SouthPanel( check ) , BorderLayout.SOUTH);
     	 Admin.Semlistwithevents.setSelectedIndex(index);
     	 mainpanel.revalidate( );
         admin.Semlistwithevents.addActionListener( this );
     	 mainpanel.repaint( );
     }
     
     else if ( source == admin.AddcourseToDB )
     { 
    	 String s=null;
		try {
			s = RM.AddCourse( admin.id );
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	 mainpanel.removeAll( );
 	 	 mainpanel.setLayout(new BorderLayout( ) );
      	 mainpanel.add(admin.Interfase( ) , BorderLayout.WEST );
      	 mainpanel.add(admin.InterfaceNorth( ), BorderLayout.NORTH );
      	 mainpanel.add(admin.Addcourse( ) , BorderLayout.CENTER );
      	 mainpanel.add(admin.SouthPanel( s ) , BorderLayout.SOUTH );
      	 mainpanel.revalidate( );
      	 mainpanel.repaint( );
     }
     
     else
     {
    	 
     }
     
     
  }

  public void listenSocket() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, KeyManagementException{

//    try{
//      server = new ServerSocket(4447); 
//    } catch (IOException e) {
//      System.out.println("Could not listen on port 4447");
//      System.exit(-1);
//    }
	  int nreq=1;
	  String S=keystorepasswordvalue.getText().toString();
    String ksName = "serverkey.jks";
    char ksPass[] = S.toCharArray();
    char ctPass[] = S.toCharArray();
try{
   KeyStore ks = KeyStore.getInstance("JKS");
   ks.load(new FileInputStream(ksName), ksPass);
   KeyManagerFactory kmf = 
   KeyManagerFactory.getInstance("SunX509");
   kmf.init(ks, ctPass);
   /////fahad 
   
   try {
       // Get private key
       Key key = ks.getKey("server", ctPass);
       if (key instanceof PrivateKey) {
           // Get certificate of public key
           java.security.cert.Certificate cert = ks.getCertificate("server");
           System.out.println("fa");
           // Get public key
           PublicKey publicKey = cert.getPublicKey();
           System.out.println(publicKey.toString()+"sd");
           // Return a key pair
           //return new KeyPair(publicKey, (PrivateKey)key);
       }
   } catch (UnrecoverableKeyException e) {
   } catch (NoSuchAlgorithmException e) {
   } catch (KeyStoreException e) {
   }
   
   ///
   SSLContext sc = SSLContext.getInstance("TLS");
   sc.init(kmf.getKeyManagers(), null, null);
   SSLServerSocketFactory ssf = sc.getServerSocketFactory();
   SSLServerSocket s 
    = (SSLServerSocket) ssf.createServerSocket(4448);
	for(;;)
	{
			newsock = (SSLSocket) s.accept();;System.out.println("### Server Side ### Creating a thread");
    		//newsock = server.accept();
    	    System.out.println("The client ip"+newsock.getInetAddress());
    		Thread T=new main(newsock,nreq);
    		T.start();
    		nreq++;
    	}
      
    } catch (IOException e) {
    	System.out.println("IO Error" + e);
      System.exit(-1);
    }

//    try{
//      in = new BufferedReader(new InputStreamReader(client.getInputStream()));
//      out = new PrintWriter(client.getOutputStream(), true);
//    } catch (IOException e) {
//      System.out.println("Accept failed: 4444");
//      System.exit(-1);
//    }
// 
//    while(true){
//      try{
//    	//read from client 
//       line=in.readLine();
//       String[] result = line.split(";");
//         for (int x=0; x<result.length; x++)
//           System.out.println(result[x]);
//        if (result[0].equals("S"))
//        {
//            out.println(S.getaction(result));
//        }
//        else if(result[0].equals("P"))
//        {
//        	String s=P.getaction(result);
//        	out.println(s);
//        }
//        else if(result[0]=="TA")
//        {
//        	out.println("no result");
//        }
//        else
//        {
//        	out.println("a");
//        }
//      	} catch (IOException e) {
//        System.out.println("Read failed");
//        System.exit(-1);
//      }
//    }
  }

//  protected void finalize(){
////Clean up 
//     try{
//        in.close();
//        out.close();
//        server.close();
//    } catch (IOException e) {
//        System.out.println("Could not close.");
//        System.exit(-1);
//    }
//  }

  public static void main(String[] args){
	    main frame = new main();
         frame.maininterface();
       for(;check;)
       {
    	   if(listen)
    	   {
        try {
			frame.listenSocket();
		} catch (UnrecoverableKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyStoreException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (CertificateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		
        }
    	   }
       }
  }
  public void mouseEntered(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	public void mouseExited(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	public void mouseReleased(MouseEvent e) {
		Object source =e.getSource();
		if(source==admin.DataBaseTable)
		admin.DataBaseTableMouseReleased();
		//else 
			//admin.DataBaseTableMouseReleased2();
				
	}
	public void mousePressed(MouseEvent e) {
		// TODO Auto-generated method stub
		
	}
	public void mouseClicked(MouseEvent e) {
		if(e.getClickCount() == 2)
		{
			JFrame frame2 = new JFrame("Activity details");
			
			Dimension FrameSize=new Dimension(400,300);
			frame2.getContentPane().setPreferredSize(FrameSize);
		    ///	frame2.setLayout();
			frame2.getContentPane().add( admin.see( ) );
			frame2.pack( );
			frame2.setLocationRelativeTo(admin.J);
			frame2.setVisible(true);
			//frame2.setDefaultCloseOperation(frame2.EXIT_ON_CLOSE);
		}		
	}
  
}